package ali

import (
	"fmt"
	"github.com/smartwalle/alipay/v3"
	"github.com/smartwalle/xid"
	"log"
	"net/http"
)

var client *alipay.Client

const (
	kAppId      = "9021000123602142"
	kPrivateKey = "MIIEpgIBAAKCAQEAr0mlPO6FA30PrpqhVSJY6uBrrAdb/M7gGAnMDqYDsz930yFsPQLU62cbM3u7gDHWNdgKpb+bKelDOkUcPwGpA8J04RcoVeuM42vOpCkmTUZx55KG00gekiHI0CVP6f0asTnkQVaJP2BrWWas1L+dS4nGiHxXLAATt14wRtxw5A7hucM1CX22fLrnShLPeozUClhfOckRjyuzOaHREOWPKsC55lPRMZ/Oje1fzaP6N1yCkIbDOzV6sM5IIzmMhpvWrd3pQIyxA59zzMxImU4qu4RkaUzDSb8fpvNft1WLmS3mFU5Md3u+0k/u3DrL7AwXPBPuD+/BP8s/jzEwXQY8UwIDAQABAoIBAQCjfsWo97EJd/TQn1or1kWpjnnfk12xiCRtR3YVk7OP1Xsmat5Safm/OASfGKHjCJkMz93ei8FmbjROfXfDLQFAiHgMG1V8DqDy3vN3GwqmuTY1EO7A01vwYaK0wpivX20uMRk9+EE74+s9EA/UwIUul+ueEpwcZlX9itTsw2Bo1gbWew3YqZBh1vhDmtu7TtgIOFjPe6qcgFNA3YL1fIOrhU8tI7D8bkZj+ca5Nqf0h4ESOnDs1BonjBVvw0+baRPjomSjd/tWePlUgMUNXAokQW7BsHYBU5Wm/sBHL+T6DGJRaeHI3TiJvGO5NWnYZwYSGSf9F4AP/mQ5ChRdTKkBAoGBAP5fMbVkwcbz/jak9GLbIe4p8KnD63ztJpcoJtuAtilvylQtn6JaAZuZ6HsA6wEtkeM+GRLWkXn2nCaDpasAjaLpSnaqrzxHJx/Kule91+WggPwBgzf3OHLlHbwzPozZ5j48XFN+7mZo8PnG5ypvCIXAE3CDEf85v+Ryu51wqR4jAoGBALBo3c0nqwuprHcs/u8PNTYfDhUuN2UGFSAVbjY+8QJTTHTa1PUMWwNEsdxgt+VTKpYZ7UpgzNkLP4MJCx9XyMk1BVMidbNk6EwtyIc6ik6eiG//ZMzyu6XpYjjqpKnxGAdolyotDmUUjZJCFSJRfUJgxE846J/8eAYDxjpGlZQRAoGBAPK2WFLxmehBRc5UJQ/ycXSztfv2gksIaasPV8xYCviMv20Ev24FHcWf3HEJljLgjXRb+0a7T8IlKiehs8Dv3TWWDkQeZuhIKC+wm48/CLMFLC3JL7CGBumybmX2K3fwLj4yEBJnaghzl4NtY4NcwLAGb0YK+nAiZVQQma4HIocrAoGBAI6jjEx4+a3JeQE36b5knpLvU1S+9N2DqIszqNTF2dwWfGi0FKM7ZU/kOKhHsAoGUBXkSuDsGlaY6LbMFik2ssw2SeLppx/xxH7sOgtVw0VEnG9qoxewYRgK+HerCo+6uMIsyKW6nrwOfVY4hpwkJdMJKVIhYr8Rxf6fCKZQMlvxAoGBAP1serhUMM8I0GEPw0kqqx36FxeyOxTxpZ0n9DDpY4VtznBp91pF/dMlN28dJv0QVqOCnP0L6Gv04U8FMR+r9ypxZnJBnt5TP0vQdWRaYvyQy/AsGhyIguzkIPkLolvIFU6irS5DaTu10Y68lI2Rf1ZXK5ZdXu02pz8EJoLi27zz"
	// TODO 设置回调地址域名
	kServerDomain = "https://6f218b65.r8.cpolar.top"
)

func check() error {
	var err error
	if client, err = alipay.New(kAppId, kPrivateKey, false); err != nil {
		log.Println("初始化支付宝失败", err)
		return err
	}

	// 加载证书
	if err := client.LoadAppCertPublicKeyFromFile("./etc/alipay/appPublicCert.crt"); err != nil {
		log.Println("加载证书发生错误", err)
		return err
	}

	if err := client.LoadAliPayRootCertFromFile("./etc/alipay/alipayRootCert.crt"); err != nil {
		log.Println("加载证书发生错误", err)
		return err
	}
	if err := client.LoadAlipayCertPublicKeyFromFile("./etc/alipay/alipayPublicCert.crt"); err != nil {
		log.Println("加载证书发生错误", err)
		return err
	}

	return client.SetEncryptKey("Hr5eOyNhmm6TIEY81DVf9g==")
}

func Pay(price, title string) (string, error) {
	err := check()
	if err != nil {
		return "", err
	}
	var tradeNo = fmt.Sprintf("%d", xid.Next())

	var p = alipay.TradePagePay{}
	p.NotifyURL = kServerDomain + "/ali/notify"
	p.ReturnURL = kServerDomain + "/alipay/callback"
	p.Subject = title
	p.OutTradeNo = tradeNo
	p.TotalAmount = price
	p.ProductCode = "FAST_INSTANT_TRADE_PAY"

	url, err := client.TradePagePay(p)
	if err != nil {
		return "", err
	}
	return url.String(), nil
}

//
//func callback(writer http.ResponseWriter, request *http.Request) {
//	request.ParseForm()
//
//	if err := client.VerifySign(request.Form); err != nil {
//		log.Println("回调验证签名发生错误", err)
//		writer.WriteHeader(http.StatusBadRequest)
//		writer.Write([]byte("回调验证签名发生错误"))
//		return
//	}
//
//	log.Println("回调验证签名通过")
//
//	var outTradeNo = request.Form.Get("out_trade_no")
//	var p = alipay.TradeQuery{}
//	p.OutTradeNo = outTradeNo
//
//	rsp, err := client.TradeQuery(p)
//	if err != nil {
//		writer.WriteHeader(http.StatusBadRequest)
//		writer.Write([]byte(fmt.Sprintf("验证订单 %s 信息发生错误: %s", outTradeNo, err.Error())))
//		return
//	}
//
//	if rsp.IsFailure() {
//		writer.WriteHeader(http.StatusBadRequest)
//		writer.Write([]byte(fmt.Sprintf("验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Msg, rsp.SubMsg)))
//		return
//	}
//	writer.WriteHeader(http.StatusOK)
//	writer.Write([]byte(fmt.Sprintf("订单 %s 支付成功", outTradeNo)))
//}

func Notify(writer http.ResponseWriter, request *http.Request) (*alipay.Notification, error) {
	err := request.ParseForm()
	if err != nil {
		return nil, err
	}
	notification, err := client.DecodeNotification(request.Form)
	if err != nil {
		log.Println("解析异步通知发生错误", err)
		return nil, err
	}
	log.Println("解析异步通知成功:", notification.NotifyId)
	var p = alipay.NewPayload("alipay.trade.query")
	p.AddBizField("out_trade_no", notification.OutTradeNo)

	var rsp *alipay.TradeQueryRsp
	if err = client.Request(p, &rsp); err != nil {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s \n", notification.OutTradeNo, err.Error())
		return nil, err
	}
	if rsp.IsFailure() {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s-%s \n", notification.OutTradeNo, rsp.Msg, rsp.SubMsg)
		return nil, err
	}
	log.Printf("订单 %s 支付成功 \n", notification.OutTradeNo)
	client.ACKNotification(writer)
	return notification, nil
}
